import './date.scss';

import { cssPrefix } from '../baseData';

import React from 'react';
import moment from 'moment';

import Popup from '../../components/popup/Popup.jsx';

window.moment = moment

import { Date, Weekdays, Days } from './DateItem.jsx';

export default class DatePicker extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      isShow: false,
      isClear: false,
      settings: {
        ...this.settings(),
        ...props
      }
    }


    let { defaultDate, date, format, hasTimePicker } = this.state.settings;
    hasTimePicker && (format = 'YYYY-MM-DD HH:mm:ss');

    defaultDate = defaultDate ? defaultDate : (date ? date : moment().format(format));
    this.state.settings.defaultDate = defaultDate;
    this.state.settings.date = date ? date : defaultDate;
    this.state.settings.format = format;

    this.changeDate = this.changeDate.bind(this);
    this.dateInputBlur = this.dateInputBlur.bind(this);
    this.changeMonth = this.changeMonth.bind(this);
    this.changeTime = this.changeTime.bind(this);
    this.getDateKey = this.getDateKey.bind(this);
  }
  settings(){
    return {
      firstDayOfWeek: 0, // 0: 周日开始，1: 周一开始
      months: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
      shortMonths: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
      weekdays: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
      shortWeekdays: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
      veryShortWeekdays: ['日', '一', '二', '三', '四', '五', '六'],
      showDatepickerInput: true,
      range: false,
      dateLayerInput: true,    // 日历弹窗中是否显示日期输入框
      hasMonthPicker: true,   // 日历弹窗是否可以直接修改月份
      hasTimePicker: false,             // 是否可以选择时间
      format: 'YYYY-MM-DD',
      minDate: '',  // 可选的最早日期
      maxDate: '',  // 可选的最晚日期
      defaultDate: '',     // 默认值
      // show: "auto",
      startDate: '',
      endDate: '',
      hasClearBtn: true,  // showDatepickerInput 为 true 时才有效
      applyCallback: null,
      cancelCallback: null,
      clearCallback: null,
      changeCallback: null,
      showCallback:null,
    }
  }

  show(){
    let { date, showCallback } = this.state.settings;
    this.setState({
      isShow: true,
      isClear: false
    })
    typeof showCallback == 'function' && showCallback(date, this);
  }

  hide(){
    let { date, cancelCallback } = this.state.settings;
    this.setState({
      isShow: false
    })
    typeof cancelCallback == 'function' && cancelCallback(date, this);
  }

  apply(){
    let { date, applyCallback, range, endDate, startDate, format } = this.state.settings,
      newDate = moment().format(format);

    startDate = startDate || newDate;
    endDate = endDate || newDate;

    if(range && moment(startDate) > moment(endDate)){
      Popup.error('开始时间不能大于结束时间');
      return;
    }
    this.setState({
      isShow: false
    });

    typeof applyCallback == 'function'
      ? range
        ? applyCallback(startDate ? startDate : newDate, endDate ? endDate : newDate, this)
        : applyCallback(date ? date : newDate, this)
      : '';
  }

  // 清除时间
  clearDate(){
    let { date, clearCallback } = this.state.settings;
    this.setState({
      isClear: true,
      isShow: false
    })
    typeof clearCallback == 'function' && clearCallback(date, this);
  }

  // 点击日历面板时
  changeDate(dateValue, isDisable, type){
    if(isDisable){return}
    let { format } = this.state.settings,
      dateKey = this.getDateKey(type);


    this.changeDateState(moment(dateValue).format(format), dateKey.key);

  }

  // 日历面板上方的input失去焦点事件
  dateInputBlur(type, e){
    let { format, minDate, maxDate } = this.state.settings,
      dateKey = this.getDateKey(type),
      value = moment(e.target.value).format(format);
    if(moment(value, format, true).isValid() && value != dateKey.date ){
      moment(value).valueOf() < moment(minDate).valueOf() && (value = minDate);  // 新的日期小于最小日期，则新日期设置为最小日期
      moment(value).valueOf() > moment(maxDate).valueOf() && (value = maxDate);  // 新的日期大于最大日期，则新日期设置为最大日期
      this.changeDateState(value, dateKey.key);
    }
  }

  // isDisable: 是否可以修改月份
  // month: change 后的月份
  changeMonth(isDisable, month, type){
    if(isDisable)return;

    let { date, minDate, maxDate, format } = this.state.settings,
      dateKey = this.getDateKey(type);

    date = moment(dateKey.date).month(month).format(format); // 新的日期

    moment(date).valueOf() < moment(minDate).valueOf() && (date = minDate);  // 新的日期小于最小日期，则新日期设置为最小日期
    moment(date).valueOf() > moment(maxDate).valueOf() && (date = maxDate);  // 新的日期大于最大日期，则新日期设置为最大日期

    this.changeDateState(date, dateKey.key);
  }

  changeTime(timeType, type, e){
    let { format } = this.state.settings,
      dateKey = this.getDateKey(type),
      value = e.target.value;

    this.changeDateState(moment(dateKey.date)[timeType](value).format(format), dateKey.key);
  }

  getDateKey(type){
    let { range } = this.state.settings,
      key = range ? (type == 'start' ? 'startDate' : 'endDate') : 'date';
    return {
      key,
      date: this.state.settings[key]
    };
  }

  changeDateState(date, key){
    let { changeCallback } = this.state.settings;

    this.setState({
      settings: {
        ...this.state.settings,
        [key]: date
      }
    }, ()=>{
      typeof changeCallback == 'function' && changeCallback(date, this);
    })
  }

  render(){

    let { isClear, isShow } = this.state,
      { name, range, date, hasClearBtn, startDate, endDate, format } = this.state.settings,
      dateProps = {
        ...this.state.settings,
        changeDate: this.changeDate,
        dateInputBlur: this.dateInputBlur,
        changeMonth: this.changeMonth,
        changeTime: this.changeTime,
        getDateKey: this.getDateKey
      },
      className = range ? `${cssPrefix}datepicker-range-wrap` : `${cssPrefix}datepicker-single-wrap`;

    className += isShow ? ` ${cssPrefix}datepicker-active` : '';

    return <div className={`${cssPrefix}datepicker-wrap`}>
      <div className={`${cssPrefix}datepicker-input-wrap`}>
        <input
          className={`${cssPrefix}datepicker-input`}
          name={name}
          value={isClear ? '' : (range ? startDate && endDate ? `${startDate} ~ ${endDate}` : '' : date) }
          type='text' readOnly
          onFocus={this.show.bind(this)}
        />
        <span
          className='icon-calendar'
          onClick={this.show.bind(this)}
        ></span>
        {
          hasClearBtn && <span className='icon-close' onClick={this.clearDate.bind(this)}></span>
        }
      </div>
      <div className={className}>
        {
          range
            ? <div className='clearfix'>
              <Date {...dateProps} type='start' date={startDate ? startDate : moment().format(format)} />
              <Date {...dateProps} type='end' date={endDate ? endDate : moment().format(format)} />
            </div>
            : <Date {...dateProps} />
        }
        <div className={`${cssPrefix}datepicker-button-wrap`}>
          <span className={`${cssPrefix}datepicker-cancel`} onClick={this.hide.bind(this)}>取消</span>
          <span className={`${cssPrefix}datepicker-apply`} onClick={this.apply.bind(this)}>确定</span>
        </div>
      </div>

    </div>
  }
}